//
//  SHVideoCapture.swift
//  SHMediaTools
//
//  Created by ace on 2023/6/21.
//

import UIKit
import AVFoundation

//struct SHVideoCapture {
////    static let sharedInstance = SHVideoCapture()
//    
//    lazy var captureSession = AVCaptureSession();
//    let captureDevice: AVCaptureDevice
//    
//}

//public typealias outputBlock = (_ sampleBuffer: CMSampleBuffer) -> Void

public class SHVideoCapture: NSObject, SHVideoCaptureProtocol {
    public func startCapture(_ outputBlock: outputBlock!) {
        self.startCapture()
        
        if (outputBlock != nil) {
            self.outputSampleBufferBlock = outputBlock
        }
    }
    

    public static let sharedInstance = SHVideoCapture()
    
    public var outputSampleBufferBlock: outputBlock!
    
    /// 视频采集绘画
    lazy var captureSession: AVCaptureSession = {
        // 1、初始化采集会话。
        let session = AVCaptureSession()
        
        let selectPreset = AVCaptureSession.Preset.low
        
        if (session.canSetSessionPreset(selectPreset)) {
            session.sessionPreset = selectPreset
            
            if (self.videoInput != nil) {
                if (session.canAddInput(self.videoInput!)) {
                    session.addInput(self.videoInput!)
                }
            }
            
            if (session.canAddOutput(self.videoOutput)) {
                session.addOutput(self.videoOutput)
            }
            
        }
        
        return session
    }()
    
    /// 视频采集设备
    lazy var captureDevice: AVCaptureDevice? = self.cameraWithPosition(position: .back)
    
    /// 视频采集线程
    lazy var captureQueue: DispatchQueue = {
        let queue = DispatchQueue(label: "com.SHVideoCapture.videoCapture")
        return queue
    }()
    
    /// 视频采集
    lazy var videoInput: AVCaptureDeviceInput? = {
        guard self.captureDevice == nil else {
            let videoInput = try? AVCaptureDeviceInput(device: self.captureDevice!)
            return videoInput
        }
        
        return nil
    }()
    
    /// 视频采集输出
    lazy var videoOutput: AVCaptureVideoDataOutput = {
        let videoOutput: AVCaptureVideoDataOutput = AVCaptureVideoDataOutput()
        videoOutput.setSampleBufferDelegate(self, queue: self.captureQueue)
//        videoOutput.videoSettings = [String(kCVPixelBufferPixelFormatTypeKey): kCVPixelFormatType_32BGRA]
        // 表示：采集的下一帧到来前，如果有还未处理完的帧，丢掉。
        videoOutput.alwaysDiscardsLateVideoFrames = true
        return videoOutput
    }()
    
    /// 获取摄像头函数
    private func cameraWithPosition(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
        //1 视频的输入
        let session = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: position)
        let devices = session.devices;
        //1.1默认获取前置摄像头
        guard let device = devices.filter({$0.position == position}).first else {
             print("get back video AVCaptureDevice failed!")
            return nil
        }
        
        return device
    }
    
    //  展示界面
    public lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)
        layer.videoGravity = .resizeAspectFill
        layer.backgroundColor = UIColor.red.cgColor
        return layer
    }()
    
    
    // 检测用户权限
//    public static func requestAccessMedia(_ type: AVMediaType, complete: (_ granted: Bool) -> Void) {
    public static func requestAccessMedia(_ type: AVMediaType) -> Bool {
        let status = AVCaptureDevice.authorizationStatus(for: type);
        
        if (status == .authorized) {
            print("有权限")
        } else {
            print("没有权限，需要弹窗获取权限")
            
            AVCaptureDevice.requestAccess(for: type) { granted in
                print("granted: \(granted)")
            }
        }
        
        return (status == .authorized)
    }
    
    // 开始
    public func startCapture() {
        if (!SHVideoCapture.requestAccessMedia(.video)) {
            return
        }
        
        if (!SHVideoCapture.requestAccessMedia(.audio)) {
            return
        }
        
        if (!self.captureSession.isRunning) {
            self.captureSession.startRunning()
        }
    }
    
    // 结束
    public func stopCapture() {
        if (self.captureSession.isRunning) {
            self.captureSession.stopRunning()
        }
    }
    
    
    override init() {
        super.init()
        print("Hello，\(123)")
    }
}

extension SHVideoCapture: AVCaptureVideoDataOutputSampleBufferDelegate {    
    public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        
        if let outputSampleBufferBlock = self.outputSampleBufferBlock {
            outputSampleBufferBlock(sampleBuffer)
        }
    }
}
